<script setup>
import { onMounted, ref, watch } from "vue";
import { useRouter, useRoute } from "vue-router";
import { AxiosError } from "axios";
import { ElMessage, ElRadioGroup, ElRadio, ElTabPane, ElTabs, ElTable, ElTableColumn, ElImage, ElIcon, ElForm, ElFormItem, ElInput, ElUpload, ElTreeSelect, ElDatePicker, ElButton, ElContainer, ElAside, ElMain, ElMessageBox } from "element-plus";
import userService from "@/services/user.service";
import departmentService from "@/services/department.service";
import positionService from "@/services/position.service";
import roleService from "@/services/role.service";
import RoleHelp from "@/components/RoleHelp.vue";
import PositionHelp from "@/components/PositionHelp.vue";
import { Search, Refresh, Plus, Edit, Delete, View, Upload, Download, Share, Close } from "@element-plus/icons-vue";

const router = useRouter();
const route = useRoute();

const currentState = ref('VIEW');
const currentId = ref(-1);

const entity = ref({});
const saveLoading = ref(false);

const treeProps = {
    value: "id",
    label: "name",
    children: "children",
    checkStrictly: true,
};
const treeData = ref([]);

const positions = ref([]);
const positionSelections = ref([]);

const positionHelpDialogVisible = ref(false);

const roles = ref([]);
const roleSelections = ref([]);

const roleHelpDialogVisible = ref(false);

onMounted(async () => {
    currentState.value = route.query.operation;
    currentId.value = Number(route.query.id);

    await loadData();

    if (currentState.value == 'CREATE') {
        create();
    } else if (currentState.value == 'EDIT') {
        edit();
    }
});

const load = async () => {
    try {
        const e = await userService.retrieve(currentId.value);
        entity.value = e;

        await loadPositions();
        await loadRoles();
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {
    }
};

const loadData = async () => {
    try {
        treeData.value = await departmentService.treeList();
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {
    }
}

const create = async () => {
    entity.value = {};
    currentState.value = 'CREATE';
}

const edit = async () => {
    await load();
    currentId.value = entity.value.id;
    currentState.value = 'EDIT';
}

const save = async () => {
    try {
        saveLoading.value = true;
        let id;
        if (currentState.value == 'CREATE') {
            id = await userService.insert(entity.value);
        } else if (currentState.value == 'EDIT') {
            await userService.update(entity.value);
            id = entity.value.id;
        } else {
            id = undefined;
        }
        if (id) {
            currentId.value = id;
            edit();
            ElMessage({ message: "保存成功", type: "success" });
        }
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {
        saveLoading.value = false;
    }
}

const uploadAvatar = async (options) => {
    return userService.uploadAvatar(entity.value.id, options.file);
};

const onUploadAvatarSuccess = async () => {
    await edit();
}

const handleDepartmentChange = (value) => {
    if (value == null || value == "") {
        entity.value.departmentId = null;
    } else {
        entity.value.departmentId = value;
    }
}

const loadPositions = async () => {
    try {
        positions.value = await positionService.findPositionsByUserId(entity.value.id);
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {

    }
}

const positionSelectionChanged = (val) => {
    positionSelections.value = val;
}

const addPositions = () => {
    positionHelpDialogVisible.value = true;
};

const removePositions = async (row) => {
    let ids = [];
    if (row != null) {
        ids = [row.id];
    } else {
        ids = positionSelections.value.map(it => it.id);
    }
    if (ids.length == 0) {
        ElMessage({ message: "请选择要删除的数据", type: "error" });
        return;
    }
    try {
        const flag = await ElMessageBox.confirm('确定要删除选中的数据吗');
        if (flag) {
            const param = {};
            param.userId = entity.value.id;
            param.positionIds = ids;
            await positionService.cancelAssign(param);
            ElMessage({ message: "删除成功", type: "success" });
            load();
        }
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {

    }
};

const removePositionRow = (row) => {
    removePositions(row);
};

const positionHelpDialogConfirmed = async (selections) => {
    console.log(selections);
    try {
        const param = {};
        param.userId = entity.value.id;
        param.positionIds = selections.map(it => it.id);
        await positionService.assign(param);
        ElMessage({ message: "新增成功", type: "success" });
        load();
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {

    }
}

const loadRoles = async () => {
    try {
        roles.value = await roleService.findRolesByUserId(entity.value.id);
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {

    }
}

const roleSelectionChanged = (val) => {
    roleSelections.value = val;
}

const addRoles = () => {
    roleHelpDialogVisible.value = true;
};

const removeRoles = async (row) => {
    let ids = [];
    if (row != null) {
        ids = [row.id];
    } else {
        ids = roleSelections.value.map(it => it.id);
    }
    if (ids.length == 0) {
        ElMessage({ message: "请选择要删除的数据", type: "error" });
        return;
    }
    try {
        const flag = await ElMessageBox.confirm('确定要删除选中的数据吗');
        if (flag) {
            const param = {};
            param.userId = entity.value.id;
            param.roleIds = ids;
            await roleService.cancelAssign(param);
            ElMessage({ message: "删除成功", type: "success" });
            load();
        }
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {

    }
};

const removeRoleRow = (row) => {
    removeRoles(row);
};

const roleHelpDialogConfirmed = async (selections) => {
    console.log(selections);
    try {
        const param = {};
        param.userId = entity.value.id;
        param.roleIds = selections.map(it => it.id);
        await roleService.assign(param);
        ElMessage({ message: "新增成功", type: "success" });
        load();
    } catch (err) {
        if (err instanceof AxiosError) {
            const msg = err.response?.data?.message || err.message;
            ElMessage({ message: msg, type: "error" });
        }
        throw err;
    } finally {

    }
}
</script>

<template>
    <ElContainer>
        <ElAside style="width: 30%;">
            <ElForm v-model="entity" label-width="120px" class="form">
                <ElFormItem label="头像" v-if="currentState != 'CREATE'">
                    <ElUpload action="" :show-file-list="false" list-type="picture-card" :http-request="uploadAvatar"
                        :on-success="onUploadAvatarSuccess">
                        <ElImage v-if="entity.avatar" :src="entity.avatar" />
                        <ElIcon v-else>
                            <Plus />
                        </ElIcon>
                    </ElUpload>
                </ElFormItem>
                <ElFormItem label="用户名">
                    <ElInput v-model="entity.username" :readonly="currentState != 'CREATE'"></ElInput>
                </ElFormItem>
                <ElFormItem label="昵称">
                    <ElInput v-model="entity.nickname"></ElInput>
                </ElFormItem>
                <ElFormItem label="启用状态">
                    <ElRadioGroup v-model:model-value="entity.status">
                        <ElRadio :label="1">是</ElRadio>
                        <ElRadio :label="0">否</ElRadio>
                    </ElRadioGroup>
                </ElFormItem>
                <ElFormItem label="部门">
                    <ElTreeSelect class="w-full" v-model="entity.departmentId" :props="treeProps" :data="treeData" clearable
                        filterable check-strictly @change="handleDepartmentChange"></ElTreeSelect>
                </ElFormItem>
                <template v-if="currentState == 'CREATE'">
                    <ElFormItem label="密码">
                        <ElInput clearable show-password v-model="entity.password" placeholder="密码" />
                    </ElFormItem>
                    <ElFormItem label="确认密码">
                        <ElInput clearable show-password v-model="entity.confirmPassword" placeholder="确认密码" />
                    </ElFormItem>
                </template>
                <ElFormItem label="邮箱">
                    <ElInput v-model="entity.email"></ElInput>
                </ElFormItem>
                <ElFormItem label="手机号">
                    <ElInput v-model="entity.phone"></ElInput>
                </ElFormItem>
                <ElFormItem label="真实姓名">
                    <ElInput v-model="entity.realName"></ElInput>
                </ElFormItem>
                <ElFormItem label="生日">
                    <ElDatePicker class="w-full" v-model="entity.birthday" type="date" format="YYYY-MM-DD"
                        value-format="YYYY-MM-DD" />
                </ElFormItem>
                <ElFormItem label="个人介绍">
                    <ElInput v-model="entity.introduce"></ElInput>
                </ElFormItem>
                <ElFormItem>
                    <ElButton type="primary" :loading="saveLoading" @click="save()">保存</ElButton>
                </ElFormItem>
            </ElForm>
        </ElAside>
        <ElMain>
            <ElTabs>
                <ElTabPane label="岗位">
                    <div class="flex mt-2">
                        <ElButton size="small" :plain="true" type="primary" :icon="Plus" @click="addPositions()"
                            :disabled="entity.id == null">
                            新增
                        </ElButton>
                        <ElButton size="small" :plain="true" type="danger" :icon="Delete" @click="removePositions()"
                            :disabled="entity.id == null">
                            删除
                        </ElButton>
                    </div>
                    <ElTable row-key="id" table-layout="auto" :data="positions"
                        @selection-change="positionSelectionChanged($event)">
                        <ElTableColumn type="selection" width="55" />
                        <ElTableColumn prop="code" label="编号"></ElTableColumn>
                        <ElTableColumn prop="name" label="名称"></ElTableColumn>
                        <ElTableColumn prop="description" label="描述"></ElTableColumn>
                        <ElTableColumn prop="operation" label="操作">
                            <template #default="scope">
                                <ElButton size="small" link type="primary" :icon="Delete"
                                    @click="removePositionRow(scope.row)" :disabled="entity.id == null">
                                    删除
                                </ElButton>
                            </template>
                        </ElTableColumn>
                    </ElTable>
                </ElTabPane>
                <ElTabPane label="角色">
                    <div class="flex mt-2">
                        <ElButton size="small" :plain="true" type="primary" :icon="Plus" @click="addRoles()"
                            :disabled="entity.id == null">
                            新增
                        </ElButton>
                        <ElButton size="small" :plain="true" type="danger" :icon="Delete" @click="removeRoles()"
                            :disabled="entity.id == null">
                            删除
                        </ElButton>
                    </div>
                    <ElTable row-key="id" table-layout="auto" :data="roles"
                        @selection-change="roleSelectionChanged($event)">
                        <ElTableColumn type="selection" width="55" />
                        <ElTableColumn prop="code" label="编号"></ElTableColumn>
                        <ElTableColumn prop="name" label="名称"></ElTableColumn>
                        <ElTableColumn prop="description" label="描述"></ElTableColumn>
                        <ElTableColumn prop="operation" label="操作">
                            <template #default="scope">
                                <ElButton size="small" link type="primary" :icon="Delete" @click="removeRoleRow(scope.row)"
                                    :disabled="entity.id == null">
                                    删除
                                </ElButton>
                            </template>
                        </ElTableColumn>
                    </ElTable>
                </ElTabPane>
            </ElTabs>

            <PositionHelp ref="positionHelpDialog" v-model:visible="positionHelpDialogVisible"
                @confirm="positionHelpDialogConfirmed">
            </PositionHelp>

            <RoleHelp ref="roleHelpDialog" v-model:visible="roleHelpDialogVisible" @confirm="roleHelpDialogConfirmed">
            </RoleHelp>
        </ElMain>
    </ElContainer>
</template>

<style scoped>
.form {
    /* max-width: 460px; */
}
</style>